// 定义泛型参数: 名称任意，一般大写  T U
// 使用泛型参数

// 定义了泛型参数A
// 形参x的类型是A
// 返回值的类型是A

// 怎么使用泛型参数A？给泛型参数传入类型 fn<number>
// 泛型参数A的类型是什么呢？使用的时候确定。使用时传入的参数的类型，就是A的类型
function fn1<A>(x: A): A {
	return x;
}

const a = fn1<number>(1);

// 泛型参数可以定义任意数量
function fn2<A, B, C>(x: A, y: B, z: C): A {
	console.log(x, y, z);
	return x;
}

fn2<number, string, boolean>(1, "string", true);

interface Person {
	name: string;
	age: number;
}
// 定义泛型参数T，继承Person类型
// 泛型参数T一定有Person类型的特点（name age）
function fn3<T extends Person>(person: T): T {
	console.log(person.name);
	console.log(person.age);
	return person;
}

interface Son extends Person {
	sex: string;
}

const p = fn3<Son>({ name: "jack", age: 18, sex: "男" });
